package com.weifly.jettydoc.check;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

import javax.swing.text.MutableAttributeSet;
import javax.swing.text.html.HTML;
import javax.swing.text.html.HTMLEditorKit;
import javax.swing.text.html.HTML.Tag;
import javax.swing.text.html.parser.ParserDelegator;

/**
 * 检查生成的html中的链接是否正确
 * 
 * @author weijx
 * @date 2011-06-17
 */
public class UrlChecker {

	public static void main(String[] args) throws Exception {
		// 文档根目录
		String docRoot = "D:\\work\\eclipse\\eclipse3.5.1_jetty\\workspace\\doc\\target\\site";
		new UrlChecker().checkRoot(new File(docRoot), false);
	}
	
	private LinkedList<File> fileList = new LinkedList<File>();
	
	private ParserDelegator parser = new ParserDelegator();
	
	private HtmlParserListener listener = new HtmlParserListener();
	
	private int line;
	
	private int id = 1;
	
	public void checkRoot(File root, boolean statistics){
		File[] subList = root.listFiles();
		for(File sub : subList){
			if(sub.isDirectory()){
				checkFolder(sub, statistics);
			}else if(sub.isFile()){
				checkFile(sub, statistics);
			}
		}
	}
	
	private void checkFolder(File folder, boolean statistics){
		try{
			fileList.addLast(folder);
			File[] subList = folder.listFiles();
			for(File sub : subList){
				if(sub.isDirectory()){
					checkFolder(sub, statistics);
				}else if(sub.isFile()){
					checkFile(sub, statistics);
				}
			}
		}finally{
			fileList.removeLast();
		}
	}
	
	private void checkFile(File file, boolean statistics){
		if(file.getName().endsWith(".html")){
			FileReader reader = null;
			try{
				fileList.addLast(file);
				reader = new FileReader(file);
				parser.parse(reader, listener, true);
			}catch(Exception e){
				e.printStackTrace();
			}finally{
				fileList.removeLast();
				try{
					reader.close();
				}catch(Exception e){}
			}
			
			if(statistics){
				// 增加网站统计代码
				List<String> lineList = new ArrayList<String>();
				try{
					reader = new FileReader(file);
					BufferedReader br = new BufferedReader(reader);
					String line = null;
					while((line=br.readLine())!=null){
						if(line.trim().startsWith("<div class=\"xright\">Copyright")){
							lineList.add("<div class=\"xright\">");
							lineList.add("<script type=\"text/javascript\">");
							lineList.add("var _bdhmProtocol = ((\"https:\" == document.location.protocol) ? \" https://\" : \" http://\");");
							lineList.add("document.write(unescape(\"%3Cscript src='\" + _bdhmProtocol + \"hm.baidu.com/h.js%3Ff365e085bf8a9b0117de53aef1245e85' type='text/javascript'%3E%3C/script%3E\"));");
							lineList.add("</script>");
							lineList.add(line.trim().substring("<div class=\"xright\">".length()));
						}else{
							lineList.add(line);
						}
					}
					// 写入文件
					BufferedWriter bw = new BufferedWriter(new FileWriter(file));
					for(String s : lineList){
						bw.write(s);
						bw.newLine();
					}
					bw.close();
				}catch(Exception e){
					e.printStackTrace();
				}finally{
					try{
						reader.close();
					}catch(Exception e){}
				}
			}
		}
	}
	
	private String getFilePath(){
		StringBuilder sb = new StringBuilder();
		for(File f : fileList){
			sb.append("/").append(f.getName());
		}
		return sb.substring(1);
	}
	
	private void handleATag(Tag t, MutableAttributeSet a, int pos){
		String name = t.toString();
		// 不是a标签则返回
		if(!"a".equalsIgnoreCase(name)){
			return ;
		}
		Object hrefKey = HTML.getAttributeKey("href");
		Object hrefObj = a.getAttribute(hrefKey);
		// href为空则返回
		if(hrefObj==null){
			return ;
		}
		String href = hrefObj.toString();
		if(href==null || href.trim().length()==0){
			return ;
		}
		
		// 是绝对地址则返回
		if(href.startsWith("http://") || href.startsWith("https://")){
			return ;
		}
		
		// 是锚点则返回
		if(href.startsWith("#")){
			return ;
		}
		
		File file = fileList.getLast();
		File linkedFile = parseLinkedFile(file, href);
		
		// System.out.println(file.getAbsolutePath());
		// System.out.println(linkedFile.getAbsolutePath());
		
		// 打印不存在的页面
		if(!linkedFile.exists()){
			String path = getFilePath();
			int idx = id++;
			System.out.println(idx + " : " + path + " [" + line + "," + pos + "] " + name + " href=" + href);
		}
	}
	
	private File parseLinkedFile(File htmlFile, String href){
		File f = htmlFile.getParentFile();
		String s = null;
		int partIdx = href.indexOf("#");
		if(partIdx==-1){
			s = href;
		}else{
			s = href.substring(0, partIdx);
		}
		while(true){
			if(s.startsWith("../")){
				f = f.getParentFile();
				s = s.substring(3);
			}else if(s.startsWith("./")){
				s = s.substring(2);
				return new File(f, s);
			}else{
				return new File(f, s);
			}
		}
	}
	
	private class HtmlParserListener extends HTMLEditorKit.ParserCallback{

		public void handleEndOfLineString(String eol) {
			line++;
		}

		public void handleEndTag(Tag t, int pos) {
			
		}

		public void handleError(String errorMsg, int pos) {
			
		}

		public void handleSimpleTag(Tag t, MutableAttributeSet a, int pos) {
			handleATag(t, a, pos);
		}

		public void handleStartTag(Tag t, MutableAttributeSet a, int pos) {
			handleATag(t, a, pos);
		}

	}

}
